package org.mcflier.appuntamento.io.driver.rss.torrent;

import java.net.MalformedURLException;
import java.net.URL;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

import org.mcflier.appuntamento.core.logger.LoggerManager;
import org.mcflier.appuntamento.data.model.TorrentList;
import org.mcflier.appuntamento.io.driver.rss.torrent.interfaces.IRssTorrentDriver;
import org.mcflier.appuntamento.io.exception.DomainRemoteResourceException;
import org.mcflier.appuntamento.io.exception.RSSConnectionException;
import org.mcflier.appuntamento.io.exception.RSSParsingException;

public abstract class AbstractRssTorrentDriver implements IRssTorrentDriver {
	
	protected Logger logger;
	private Properties properties;
	private List<String> hdResources;
	private List<String> sdResources;
	private String domain;
	
	public AbstractRssTorrentDriver(){
		this.logger = LoggerManager.getInstance().getLogger(this.getClass().getName());
		this.properties = null;
		
		this.domain = null;
		this.hdResources = new ArrayList<String>();
		this.sdResources = new ArrayList<String>();
	}
	
	public void init(Properties properties){
		if(properties == null)
			throw new NullPointerException("Properties argument must not be null");
		
		this.properties = properties;
	}

	@Override
	public void addDomain(String domain) throws MalformedURLException {
		if(domain==null)
			throw new NullPointerException("Domain must not be null");
		
		try {
			URL url = new URL(
					(domain.toLowerCase().startsWith("http://")
							|| domain.toLowerCase().startsWith("https://"))?
									domain:"http://"+domain);
			this.domain = domain;
		} catch (MalformedURLException e) {
			this.logger.warning("Domain: '"+domain+"' is not valid\n"+e.getMessage());
			throw e;
		}
	}
	
	private void checkLink(String link) throws DomainRemoteResourceException, MalformedURLException{
		try {
			URL url = new URL(link);
			if(!url.getHost().toLowerCase().equals(this.domain.toLowerCase()))
				throw new DomainRemoteResourceException("This resource ("+link+") doesn't correspond with this domain ("+this.domain+")");
		} catch (MalformedURLException e) {
			this.logger.warning("Adding resource link is not valid: "+link);
			throw e;
		}
	}

	@Override
	public void addHDResource(String link) throws MalformedURLException, DomainRemoteResourceException {
		if(link==null)
			throw new NullPointerException("Adding resource link must not be null");
		this.checkLink(link);
		
		if(!this.hdResources.contains(link.trim()))
			this.hdResources.add(link.trim());
		else
			this.logger.warning("The hd resource '"+link+"' is already stored");
	}

	@Override
	public void addSDResource(String link) throws MalformedURLException, DomainRemoteResourceException {
		if(link==null)
			throw new NullPointerException("Adding resource link must not be null");
		this.checkLink(link);
		
		if(!this.sdResources.contains(link.trim()))
			this.sdResources.add(link.trim());
		else
			this.logger.warning("The sd resource '"+link+"' is already stored");
	}
	
	protected List<String> getHDResources(){
		return this.hdResources;
	}
	
	protected List<String> getSDResources(){
		return this.sdResources;
	}

	@Override
	public abstract List<TorrentList> getHDTorrents() throws RSSConnectionException, RSSParsingException;

	@Override
	public abstract List<TorrentList> getHDTorrents(Timestamp since) throws RSSConnectionException, RSSParsingException;
	
	@Override
	public abstract List<TorrentList> getSDTorrents() throws RSSConnectionException, RSSParsingException;

	@Override
	public abstract List<TorrentList> getSDTorrents(Timestamp since) throws RSSConnectionException, RSSParsingException;
}
